// *********************************************************
//      Copyright (c) Kosta Gaitanis
//      All rights reserved
//
//      k.gaitanis@gmail.com
//
// *********************************************************

#include <QDoubleSpinBox>

#include "MaterialWidget.h"

MaterialWidget::MaterialWidget(Material *material, QWidget *parent) :
    CollapsibleWidget(parent),
    m_material(0),
    m_ambient(new ColorPickerWidget("Ambient")),
    m_diffuse(new ColorPickerWidget("Diffuse")),
    m_specular(new ColorPickerWidget("Specular")),
    m_emission(new ColorPickerWidget("Emission")),
    m_shininess(new QDoubleSpinBox()),
    m_transparency(new QDoubleSpinBox())
{
    //m_diffuse->setShowAlpha(true);
    m_shininess->setRange(0.0, 127.0);
    m_transparency->setRange(0.0, 1.0);
    m_transparency->setSingleStep(0.1);
    setMaterial(material);

    connect(m_ambient, SIGNAL(colorChanged(QColor)), this, SLOT(onAmbientChanged(QColor)));
    connect(m_diffuse, SIGNAL(colorChanged(QColor)), this, SLOT(onDiffuseChanged(QColor)));
    connect(m_specular, SIGNAL(colorChanged(QColor)), this, SLOT(onSpecularChanged(QColor)));
    connect(m_emission, SIGNAL(colorChanged(QColor)), this, SLOT(onEmissionChanged(QColor)));
    connect(m_shininess, SIGNAL(valueChanged(double)), this, SLOT(onShininessChanged(double)));
    connect(m_transparency, SIGNAL(valueChanged(double)), this, SLOT(onTransparencyChanged(double)));

    QWidget* widget = new QWidget();
    QVBoxLayout *layout = new QVBoxLayout(widget);
    layout->addWidget(m_ambient);
    layout->addWidget(m_diffuse);
    layout->addWidget(m_specular);
    layout->addWidget(m_emission);
    QHBoxLayout *hl = new QHBoxLayout();
    hl->addWidget(new QLabel("Shininess"), 1, Qt::AlignRight);
    hl->addWidget(m_shininess);
    layout->addLayout(hl);

    QHBoxLayout *hl2 = new QHBoxLayout();
    hl2->addWidget(new QLabel("Transparency"), 1, Qt::AlignRight);
    hl2->addWidget(m_transparency);
    layout->addLayout(hl2);

    widget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
    setWidget(widget);
    setTitle("Material");
}

MaterialWidget::~MaterialWidget()
{
}

void MaterialWidget::setMaterial(Material *material)
{
    m_material = material;
    if (m_material) {        
        setAmbient(m_material->getAmbient());
        setDiffuse(m_material->getDiffuse());
        setSpecular(m_material->getSpecular());
        setEmission(m_material->getEmission());
        setShininess(m_material->getShininess());
        showAll();

    } else {
        setTitle("Material : (none)");
        hideAll();
    }
}

const Material *MaterialWidget::getMaterial() const
{
    return m_material;
}

void MaterialWidget::setAmbient(const QColor &color)
{
    m_ambient->setColor(color);
}

void MaterialWidget::setDiffuse(const QColor &color)
{
    m_diffuse->setColor(color);
    m_transparency->setValue(color.alphaF());
}

void MaterialWidget::setSpecular(const QColor &color)
{
    m_specular->setColor(color);
}

void MaterialWidget::setEmission(const QColor &color)
{
    m_emission->setColor(color);
}

void MaterialWidget::setShininess(double shininess)
{
    m_shininess->setValue(shininess);
}

void MaterialWidget::onAmbientChanged(const QColor &color)
{
    if (m_material) {
        m_material->setAmbient(color);
        emit changed();
    }
}

void MaterialWidget::onDiffuseChanged(const QColor &color)
{
    if (m_material) {
        QColor c = color;
        c.setAlphaF(m_transparency->value());
        m_material->setDiffuse(c);
        emit changed();
    }
}

void MaterialWidget::onSpecularChanged(const QColor &color)
{
    if (m_material) {
        m_material->setSpecular(color);
        emit changed();
    }
}

void MaterialWidget::onEmissionChanged(const QColor &color)
{
    if (m_material) {
        m_material->setEmission(color);
        emit changed();
    }
}

void MaterialWidget::onShininessChanged(double shininess)
{
    if (m_material) {
        m_material->setShininess(shininess);
        emit changed();
    }
}

void MaterialWidget::onTransparencyChanged(double transparency)
{
    if (m_material) {
        QColor c = m_diffuse->getColor();
        c.setAlphaF(transparency);
        m_material->setDiffuse(c);
        emit changed();
    }
}

void MaterialWidget::hideAll()
{
    m_ambient->hide();
    m_diffuse->hide();
    m_specular->hide();
    m_emission->hide();
}

void MaterialWidget::showAll()
{
    m_ambient->show();
    m_diffuse->show();
    m_specular->show();
    m_emission->show();
}


